﻿using System;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using Red.Core.GoogleAnalytics;
using ViewModel = Red.Launcher.ViewModels.Packages;

namespace Red.Launcher.Menus.Packages
{
    public partial class AvailablePackagesList
    {
        readonly string _analyticsCategory = typeof( AvailablePackagesList ).Name;

        private readonly string[] interestingBuildSystemProperties =
        {
            "ActivePackage",
            "InstallingPackage",
            "FetchInProgress"
        };

        partial void InitializeAnalytics()
        {
            InitializeContextMenu();

            Manager.PropertyChanged += OnBuildSystemPropertyChanged;

            OnStabilityVote += Analytics_OnPackageStabiltyVote;
            
            _packageList.Sorting += ( object sender, DataGridSortingEventArgs e ) =>
            {
                // Bizarrely, this event happens before e.Column.SortDirection is set, but after e.Column.SortMemberPath.
                // So we can take e.Column.SortMemberPath as it is, but we need to figure out what e.Column.SortDirection will be

                ListSortDirection direction;

                switch( e.Column.SortDirection )
                {
                    case ListSortDirection.Ascending:
                        direction = ListSortDirection.Descending;
                        break;

                    case ListSortDirection.Descending:
                    case null:
                        direction = ListSortDirection.Ascending;
                        break;

                    default:
                        throw new NotImplementedException();
                }

                GoogleAnalyticsService.Instance.SendEvent( "Sort", _analyticsCategory, String.Format( @"{0} {1}", e.Column.SortMemberPath, direction ) );
            };

            _refreshPackagesButton.Click += ( object sender, RoutedEventArgs e ) => { GoogleAnalyticsService.Instance.SendEvent( "Refresh Packages clicked", _analyticsCategory, Manager.PackageTitle ); };
            _loadMorePackagesButton.Click += ( object sender, RoutedEventArgs e ) => { GoogleAnalyticsService.Instance.SendEvent( "Load more packages clicked", _analyticsCategory, Manager.PackageTitle ); };
        }

        void Analytics_OnPackageStabiltyVote( int buildId, bool stable )
        {
            if ( stable )
            {
                GoogleAnalyticsService.Instance.SendEvent( "Build voted stable", _analyticsCategory, buildId.ToString() );
            }
            else
            {
                GoogleAnalyticsService.Instance.SendEvent( "Build voted unstable", _analyticsCategory, buildId.ToString() );
            }
        }

        private void InitializeContextMenu()
        {
            ContextMenu menu = (ContextMenu)_packageList.FindResource( "DataRowContextMenu" );

            foreach ( MenuItem mi in menu.Items )
            {
                string header = (string)mi.Header;
                mi.Click += ( object clickSender, RoutedEventArgs clickArgs ) =>
                {
                    ViewModel.Package pkg = (ViewModel.Package)_packageList.SelectedItem;
                    GoogleAnalyticsService.Instance.SendEvent( "Context Menu: " + header, _analyticsCategory, pkg.Name );
                };
            }
        }

        private void OnBuildSystemPropertyChanged( object sender, PropertyChangedEventArgs e )
        {
            bool interestedInProperty = Array.IndexOf( interestingBuildSystemProperties, e.PropertyName ) > -1;
            if ( interestedInProperty )
            {
                PropertyInfo property = Manager.GetType().GetProperty( e.PropertyName );

                object value = property.GetValue( Manager, null );

                // Ignore null values for now (Typically the properties will cycle
                // through null as they're being set to something valid)
                if ( value != null )
                {
                    string valueStr = value.ToString();

                    GoogleAnalyticsService.Instance.SendEvent( e.PropertyName, $"{_analyticsCategory} {Manager.PackageTitle}", valueStr );
                }
            }
        }
    }
}
